home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / pdoxwin / pi0495.zip / LW9504.EXE / litprog.nw (.txt) < prev    next >
LaTeX Document  |  1995-01-23  |  33KB  |  708 lines

  1. % $Header: d:/tcc/informan/litprog.nw%v 2.2 1995/01/16 11:19:51 LEEW Exp LEEW $
  2. \documentstyle[noweb,twocolumn]{article}
  3. \noweboptions{longchunks,nomargintag,noidentxref,webnumbering}
  4. \pagestyle{empty}
  5. \let\xnwnotused=\nwnotused
  6. \let\nwnotused=\nwoutput
  7. \def\nwendcode{\endtrivlist \endgroup \par\noindent}  % to avoid extra page breaks
  8. \def\RCSdef $#1${\typeout{RCS keyword string: $#1$}\RCS@def#1: {} :.}
  9. \def\RCS@def#1: #2 :#3.{\expandafter\def\csname RCS#1\endcsname{#2}}
  10. \setlength{\oddsidemargin}{-.5in}
  11. \setlength{\evensidemargin}{-.5in}
  12. \setlength{\columnsep}{.25in}
  13. \setlength{\textwidth}{7.5in}
  14. \setlength{\topmargin}{-.5in}
  15. \setlength{\textheight}{10in}
  16. \setlength{\headheight}{0in}
  17. \setlength{\headsep}{0in}
  18. \setlength{\parskip}{8pt plus 2pt minus 1.5pt}
  19. \setlength{\parindent}{0in}
  20. \RCSdef $Date: 1995/01/16 11:19:51 $
  21. \RCSdef $Revision: 2.2 $
  22. \RCSdef $Workfile:   litprog.nw  $
  23. \RCSdef $Author: LEEW $
  24. \raggedright
  25. \def\dos/{{\sc dos}}
  26. \def\windows/{Windows}
  27. \def\unix/{{\sc unix}}
  28. \def\awk/{Awk}
  29. \def\web/{{\tt WEB}}
  30. \def\noweb/{{\tt noweb}}
  31. \def\nuweb/{Nuweb}
  32. \def\funnelweb/{FunnelWeb}
  33. \def\wordweb/{WinWordWEB}
  34. \def\clip/{CLiP}
  35. \def\notangle/{{\tt notangle}}
  36. \def\noweave/{{\tt noweave}}
  37. \def\pal/{PAL}
  38. \def\objectpal/{ObjectPAL}
  39. \def\basic/{BASIC}
  40. \def\paltable/{\verb"easter1.db"}
  41. \def\opaltable/{\verb"easter2.db"}
  42. \def\menuitem#1{``#1''}
  43. \def\aside{\noindent{\bf Aside:}  }
  44. \def\LL{<{}<}\def\GG{>{}>}
  45. \title{Literate Programming in \pal/ and \objectpal/}
  46. \author{Lee Wittenberg\thanks{Current address:  Computer
  47. Science Department, Kean College of New
  48. Jersey, Union, NJ 07083.}\\\em Tipton Cole \& Company\\\em 3006 Bee Cave Road, Suite
  49. B-200\\\em Austin, TX   78746\\\em (512)~329--0060\\\tt leew@pilot.njin.net}
  50. \begin{document}
  51. \maketitle
  52. \thispagestyle{empty}
  53. \section{Introduction}
  54. A quiet revolution is taking place in programming circles---a
  55. revolution called ``literate programming.''  In 1972, Edsger
  56. Dijkstra~\cite{dijkstra-notes}
  57. wished for a ``program written down as I can understand it, I want it
  58. written down as I would like to explain it to
  59. someone.''  Ten years later, Donald Knuth developed the original \web/
  60. system, coining the phrase ``literate programming'' in the process.
  61. Literate programming is precisely what Dijkstra wanted:  the ability to
  62. write a program as you would explain it to another human being, rather
  63. than as your compiler would have it.
  64. \section{Literate Programming}
  65. The literate programming
  66. philosophy is that a program needs to be readable by both
  67. humans and computers, but these two audiences have quite
  68. different needs.  Computers need the program to have a fairly
  69. rigid syntax, usually with names declared before their use.
  70. Human beings, on the other hand, prefer a somewhat looser
  71. style, and often like to see how a name is used before worrying
  72. about how it is defined.  Section headings,
  73. cross-references, charts, graphs, footnotes, and the like are
  74. similarly helpful to humans, but irrelevant to a computer.  The
  75. best possible documentation, therefore, will recognize the needs
  76. of both audiences.
  77. A literate program, commonly called a {\em web}, consists of
  78. alternating {\em chunks\/} of descriptive text and code.  The
  79. chunks are organized for the human reader.
  80. Usually, each text chunk describes the following code chunk,
  81. and makes full use of appropriate word processing techniques.
  82. Each code chunk has a name, which can be used in other code
  83. chunks to refer to that particular piece of code.
  84. The code chunks can be extracted from the web and placed in
  85. order suitable for a compiler (or interpreter).  This process
  86. is called {\em tangling\/} the web.  The process of typesetting the
  87. web to produce a human-readable document is called {\em weaving}.
  88. \section{Programming with \noweb/}
  89. I do all of my \pal/ and \objectpal/ programming using \noweb/~\cite{noweb},
  90. a literate programming tool by Norman Ramsey.  A \noweb/ program
  91. is a text file, usually with a `{\tt .nw}' extension.  Text
  92. chunks are introduced by the symbol `\verb"@"' on a line by
  93. itself, code chunks by a line containing
  94. the chunk's name enclosed in
  95. a set of double angle brackets, `{\tt\LL}' and~`{\tt\GG}', followed by
  96. an equals sign.
  97. Figure~\ref{nw-example} gives an example of an extremely
  98. simple \pal/ web.
  99. \begin{figure}[htbp]\begin{quote}
  100. \tt\raggedright
  101. This is a trivial example of a PAL\\
  102. web.  It displays a ``hello'' message\\
  103. and then sleeps for a bit\\
  104. before it's done.\\
  105. \LL{}*\GG=\\
  106. MESSAGE "Hello, world!"\\
  107. SLEEP \LL{}An appropriate interval\GG\\
  108. How long is appropriate?\\
  109. Let's say 2000, for now.\\
  110. \LL{}An appropriate interval\GG=\\
  111. 2000\\
  112. \end{quote}
  113. \caption{\label{nw-example}A simple \pal/ web.}\end{figure}
  114. Note the use of the code chunk
  115. {\tt\LL}\verb"An appropriate interval"{\tt\GG} in the definition of
  116. {\tt\LL}\verb"*"{\tt\GG}.
  117. Tangling in
  118. \noweb/ is accomplished with the \notangle/ command.  Assuming that the web in
  119. Figure~\ref{nw-example} is in the file \verb"example.nw", the \dos/ command
  120. $$\mbox{\verb"notangle example.nw > example.sc"}$$
  121. tangles it.
  122. The output is redirected to create the file \verb"example.sc".
  123. Figure~\ref{sc-example} shows the resulting script.
  124. \begin{figure}[htbp]
  125. \begin{quote}\begin{verbatim}
  126. MESSAGE "Hello, world!"
  127. SLEEP 2000
  128. \end{verbatim}\end{quote}
  129. \caption{\label{sc-example}The result of tangling Figure~\protect\ref{nw-example}}
  130. \end{figure}
  131. By default, tangling begins with the~{\tt\LL*\GG} chunk (it is possible
  132. to specify a different chunk on the command line).  As \notangle/ copies
  133. this ``root'' chunk to its output, it replaces each chunk name it
  134. encounters with the appropriate definition, so
  135. \verb"SLEEP "{\tt\LL}\verb"An appropriate interval"{\tt\GG} becomes
  136. \verb"SLEEP 2000" in the output, and the resulting program
  137. is pretty much what you would expect.
  138. \label{weaving}
  139. But the real payoff comes with \notangle/'s companion program, \noweave/,
  140. which produces a beautifully formatted version of the web, designed to be
  141. read by humans.  Figure~\ref{noweave-output} is the result.
  142. \begin{figure}[hbtp]\begin{quotation}
  143. \nwbegindocs{1}
  144. This is a trivial example of a PAL
  145. web.  It displays a ``hello'' message
  146. and then sleeps for a bit
  147. before it's done.
  148. \nwenddocs{}
  149. \nwbegincode{2}
  150. \moddef{*~{\footnotesize\rm1}}\endmoddef
  151. MESSAGE "Hello, world!"
  152. SLEEP \LA{}An appropriate interval~{\footnotesize\rm2}\RA{}
  153. \xnwnotused{*}
  154. \nwendcode
  155. \nwbegindocs{3}
  156. How long is appropriate?
  157. Let's say 2000, for now.
  158. \nwenddocs
  159. \nwbegincode{4}
  160. \moddef{An appropriate interval~{\footnotesize\rm2}}\endmoddef
  161. \nwcodecomment{This code is used in chunk 1.}
  162. \nwendcode
  163. \end{quotation}
  164. \caption{\label{noweave-output}Formatted output from
  165. Figure~\protect\ref{nw-example}}
  166. \end{figure}
  167. The text chunks are formatted in a roman font, with paragraphs
  168. properly indented.  The code chunks are set in a fixed-width typewriter
  169. font, with chunk names in italics (and the~{\tt\LL}\thinspace{\tt\GG} pairs
  170. replaced by~\LA\thinspace\RA).  The chunks are also {\em
  171. cross-referenced\/}:  each chunk is numbered, and has a footnote that tells where
  172. it is used, if at all.  Since this example is so short, there isn't much need for cross-referencing,
  173. but this feature is invaluable in a web of any size.
  174. \section{\noweb/ in Action}
  175. \let\nwnotused=\nwoutput
  176. The best way to understand what literate programming is all about is to
  177. build a web.  This
  178. article is actually a web containing two programs: one in \pal/~4.x,
  179. the other in \objectpal/.  From a single source file, {\tt\RCSWorkfile},
  180. \noweb/ generated
  181. a typeset copy of this article, a \pal/ script, and an \objectpal/
  182. method.
  183. Since the purpose of this article is to introduce the concept of literate
  184. programming, and not to discuss interesting Paradox programming tricks,
  185. I have chosen to implement a fairly simple algorithm and to make the
  186. \pal/ script and the \objectpal/ method do pretty much the same
  187. thing.  Both calculate dates of Easter for a given range of
  188. years, and create a table---keyed to the year---containing the results.
  189. The algorithm is from Knuth~\cite{knuth}.  Since expressions and
  190. identifiers are pretty much the same in \pal/ and \objectpal/,
  191. the same variable names can be used for both implementations. The
  192. algorithm-related code chunks accompany the algorithm.
  193. \label{same code}
  194. \newcounter{step}
  195. \begin{list}{\bf Step~\arabic{step}.}%
  196.     {\usecounter{step}\settowidth{\labelwidth}{\bf Step 10.}%
  197.      \setlength{\leftmargin}{\labelwidth}\addtolength{\leftmargin}{\labelsep}}
  198. \item[]
  199. Let $y$ be the year for which the date of Easter is desired.
  200. \item
  201. Set $g\gets(y\bmod19)+1$.  Easter calculations depend on a 19-year cycle.
  202. A year's place in this cycle is called its ``golden number.''
  203. <<Calculate the golden number>>=
  204. golden_number = MOD(easter_year, 19)
  205.                     + 1
  206. @ \par
  207. Note that, in place of the single letters $y$ and $g$, I use
  208. [[easter_year]] and [[golden_number]] as identifiers, preferring good programming
  209. style to mathematical consistency.  I use [[easter_year]] instead of
  210. [[year]], because the latter is a reserved word in \pal/~4.x.
  211. \item
  212. Set $c \gets \left\lfloor y/100 \right\rfloor + 1$.  This step
  213. determines the century
  214. in which the year occurs (more or less---this description isn't quite
  215. accurate for years that are divisible by 100, but it will do).
  216. Note that `$\left\lfloor\,\right\rfloor$' is
  217. mathematical notation for the ``floor'' function.
  218. <<Calculate the century number>>=
  219. century = FLOOR(easter_year/100) + 1
  220. @ \par
  221. \item
  222. Set $x \gets \left\lfloor 3c/4 \right\rfloor - 12$, and $z \gets \left\lfloor (8c+5)/25
  223. \right\rfloor - 5$.  A couple of corrections are necessary due to
  224. idiosyncracies in the Gregorian calendar.  The former, $x$, calculates the number
  225. of years divisible by~4 in which there is no leap year, such as 1900.
  226. The latter, $z$, is a special correction designed to keep Easter
  227. in step with the moon's orbit.
  228. <<Calculate necessary corrections>>=
  229. leap_year_correction
  230.     = FLOOR(3*century/4) - 12
  231. lunar_correction
  232.     = FLOOR((8*century+5)/25) - 5
  233. @ \par
  234. \item
  235. Set $d \gets \left\lfloor 5y/4 \right\rfloor - x - 10$.  This tricky little formula
  236. computes a date that falls on a Sunday.
  237. <<Find Sunday>>=
  238. sunday = FLOOR(5*easter_year/4)
  239.             - leap_year_correction
  240.             - 10
  241. @ \par
  242. \item
  243. Set $e \gets (11g+20+z-x) \bmod 30$.  If $e = 25$ and the golden
  244. number~$g$ is greater than~11, or if $e=24$, increase $e$ by 1.  The
  245. ``epact,'' $e$, is used to calculate when a full moon occurs.
  246. <<Calculate the epact>>=
  247. epact = MOD(11*golden_number + 20
  248.             + lunar_correction
  249.             - leap_year_correction,
  250.             30)
  251. IF (epact = 25 AND golden_number > 11)
  252.     OR (epact = 24)
  253.     epact = epact + 1
  254. ENDIF
  255. @ \par
  256. \item
  257. Set $m \gets 44 - e$.  If $m < 21$ then set $m \gets m + 30$.  Easter is
  258. defined as ``the first Sunday following the first full moon which occurs
  259. on or after March~21.''  This formula finds the first full moon after
  260. March~21.
  261. <<Find the full moon>>=
  262. full_moon = 44 - epact
  263. IF full_moon < 21
  264.     full_moon = full_moon + 30
  265. ENDIF
  266. @ \par
  267. \item
  268. Set $n \gets m + 7 - ((d+m) \bmod 7)$.  This formula finds the Sunday
  269. immediately after the aforementioned full moon.
  270. <<Find Easter Sunday>>=
  271. easter_sunday = full_moon + 7
  272.     - MOD(sunday + full_moon, 7)
  273. @ \par
  274. \item
  275. If $n > 31$, the date is $(n-31)$ April; otherwise it is $n$ March.
  276. <<Get the month>>=
  277. IF easter_sunday > 31
  278.     easter_sunday
  279.         = easter_sunday - 31
  280.     easter_month = "April"
  281.     easter_month = "March"
  282. ENDIF
  283. \end{list}
  284. Putting it all together:
  285. <<Calculate the date of Easter>>=
  286. <<Calculate the golden number>>
  287. <<Calculate the century number>>
  288. <<Calculate necessary corrections>>
  289. <<Find Sunday>>
  290. <<Calculate the epact>>
  291. <<Find the full moon>>
  292. <<Find Easter Sunday>>
  293. <<Get the month>>
  294. The desired date is contained in the
  295. variables [[easter_sunday]], [[easter_month]],
  296. and [[easter_year]].
  297. \bigskip\aside
  298. Notice that I've been working bottom-up rather than top-down, first coding the
  299. algorithm steps, then putting them together when all the steps have
  300. been coded.
  301. This goes against all received wisdom about good programming practice,
  302. but literate programming seems to change some of the rules.  The primary
  303. focus in a literate program is explaining it to the reader.  In a case
  304. like this, where the algorithm already exists, it's much more natural to
  305. develop a program as I have done, and easier for the reader
  306. to understand, as well.  However, when I don't have an algorithm already
  307. prepared, I tend to write top-down, using the chunks for old-fashioned
  308. stepwise refinement, as you shall see in the following.
  309. \subsection{A \pal/~4.x Script}
  310. \label{pal script}
  311. Rather than bother with any input, the \pal/ script
  312. builds a table, \paltable/, that contains dates of Easter
  313. calculated for the years 1950 through~2000.  After creating the
  314. table, the program iterates over the years, adding an entry to the table for
  315. each year.
  316. <<EASTER.SC>>=
  317. <<Create the \paltable/ table>>
  318. FOR easter_year FROM 1950 TO 2000
  319.     <<Calculate the date of Easter>>
  320.     <<Add the date to \paltable/>>
  321. ENDFOR
  322. <<Clean up the workspace>>
  323. The \verb"-R" option tells \notangle/ which code chunk to begin
  324. with, so the command
  325. $$\mbox{\verb"notangle -REASTER.SC litprog.nw > easter.sc"}$$
  326. extracts the \pal/ script, creating the \verb"EASTER.SC" file.
  327. The easiest way to clean up is to issue the [[RESET]]
  328. command.  It has the disadvantage of removing anything that was on the
  329. workspace before the script started, but will do for this simple example.
  330. <<Clean up the workspace>>=
  331. RESET
  332. \subsubsection{Creating the table}
  333. \label{table structure}
  334. The \paltable/ table will have three
  335. fields:  {\em year}, {\em month}, and {\em day}.  {\em Month\/} and {\em
  336. day\/} represent the date of Easter for the specified {\em year}, which
  337. naturally enough, is the key field.  {\em Year\/} and {\em day\/} are
  338. both numeric (short numbers will do), while {\em month\/} is alphanumeric
  339. (5~characters will suffice as Easter occurs only in March or April).
  340. The program has to put the table's image on the workspace and
  341. get into Coedit mode before adding entries.  Since
  342. many table operations require subsidiary variables, which may need
  343. initialization, the {\LA{}Any other initializations needed for
  344. \paltable/\RA} chunk is useful for writing initialization code
  345. wherever in the web is most appropriate, yet insuring that the
  346. initialization is performed immediately after the table is
  347. created.
  348. <<Create the \paltable/ table>>=
  349. CREATE "easter1"
  350.     "Year"  :   "S*",
  351.     "Month" :   "A5",
  352.     "Day"   :   "S"
  353. <<Any other initializations needed for \paltable/>>
  354. COEDIT "easter1"
  355. \subsubsection{Adding an Easter date to the table}
  356. [[APPENDARRAY]] appears to be the
  357. simplest technique \pal/~4.x provides for adding records to a table.
  358. <<Add the date to \paltable/>>=
  359. newdate[2] = easter_year
  360. newdate[3] = easter_month
  361. newdate[4] = easter_sunday
  362. APPENDARRAY newdate
  363. Unlike simple variables, the [[newdate]] array must be declared before it
  364. is used.
  365. Its first element refers to the \paltable/ table.
  366. <<Any other initializations needed for \paltable/>>=
  367. ARRAY newdate[4]
  368. newdate[1] = "easter1"
  369. @ %def newdate
  370. \subsubsection{A minor problem}
  371. Unfortunately, \pal/~4.x does not provide a [[FLOOR]] function, although
  372. \objectpal/ does.  Since the Easter algorithm never passes
  373. a negative number to [[FLOOR]], the [[INT]] function provides a cheap
  374. substitute.
  375. <<Any other initializations needed for \paltable/>>=
  376. PROC FLOOR(n)
  377.     RETURN INT(n)
  378. ENDPROC
  379. @ %def FLOOR
  380. \aside
  381. Notice the $\mathord{+}\mathord{\equiv}$ in this chunk
  382. definition.  \noweave/
  383. uses this to indicate that the chunk has already been defined, and that
  384. the code in this definition will be concatenated with the code from
  385. previous definitions when the web is tangled.
  386. \subsubsection{\pal/ wrapup}
  387. The \pal/ script is now complete.  Although simple, it demonstrates
  388. the literate programming style quite well.  Each piece of the script is small and
  389. easy to understand.  Each non-trivial part of the program is relegated to
  390. a chunk, whose name is usually a complete sentence.
  391. Since chunk names are typographically distinct from the actual
  392. code, they are much easier to read than procedure names would be.  In
  393. addition, {\em there is no run-time overhead involved in using
  394. chunks}, as there would be if I had used procedures for refinements.
  395. Each chunk is accompanied by a complete description of what the chunk
  396. does, including explanations of {\em why\/} things were (or weren't) done
  397. in a particular way.
  398. Observations that would be intrusive in standard program comments fit
  399. quite well in these descriptions.  {\em The program is organized for the
  400. human reader, not the compiler}.
  401. \subsection{An \objectpal/ Method}
  402. \noweb/ is language-independent; it doesn't care whether you are
  403. programming in \pal/, \objectpal/, or even Pascal or~C.  \notangle/'s \verb"-R"
  404. option makes it possible to include programs written in several different
  405. languages in a single web.\footnote{This is particularly useful when a
  406. program is to be invoked by one or more batch files.  The batch files can
  407. be in the same web as the program they invoke, and can be easily updated
  408. whenever necessary due to program changes.}
  409. As I mentioned earlier (Section~\ref{same code}), with a little bit of
  410. care, it is possible to share code between \pal/ and \objectpal/
  411. applications.  If it is necessary to maintain both a \dos/
  412. and \windows/ version of a program, putting them in the same web will
  413. help keep them ``in sync,'' making it much less likely that any changes
  414. will render the two versions incompatible.
  415. A useful technique in \objectpal/ is to write a program as a [[pushButton]]
  416. method, linking its execution to a button on some form.  I create
  417. such a method here, assuming that it will be attached to a button
  418. labelled ``Generate Easter Table'' on some form.
  419. I use the \verb".txt" extension for \objectpal/ files, because that's
  420. what the Paradox for Windows \menuitem{\underline{E}dit$|$Paste Fro\underline{m} File}
  421. menu item seems to prefer.
  422. <<EASTER.TXT>>=
  423. METHOD pushButton(VAR eventInfo Event)
  424.     <<Local\/ [[pushButton]] variables>>
  425. ENDVAR
  426.     <<Generate the \opaltable/ table>>
  427. ENDMETHOD
  428. @ %def pushButton eventInfo
  429. In \objectpal/, all variables have to be declared.  If the web
  430. didn't also contain a \pal/~4.x script, I would have declared these variables
  431. as they made their appearence in the algorithm.  Since I didn't do it then,
  432. I'd better do it now.  The variables are declared to be of type
  433. [[Number]] (except for [[easter_month]], which is a [[String]]),
  434. rather than [[SmallInt]] or [[LongInt]], because for some
  435. inexplicable reason, \objectpal/ gets upset\footnote{At least
  436. it used to; I don't know about~5.0.} when one tries to assign the
  437. result of [[FLOOR]] to an integer variable (even though the result {\em
  438. must\/} be integral).
  439. <<Local\/ [[pushButton]] variables>>=
  440.     easter_year            Number
  441.     easter_month           String
  442.     easter_sunday          Number
  443.     golden_number          Number
  444.     century                Number
  445.     leap_year_correction   Number
  446.     lunar_correction       Number
  447.     sunday                 Number
  448.     epact                  Number
  449.     full_moon              Number
  450. @ %def easter_year easter_month easter_sunday golden_number century
  451. @ %def leap_year_correction lunar_correction sunday epact full_moon
  452. Since the form can take care of all necessary input,
  453. [[FirstYear]] and [[LastYear]] will control the [[FOR]] loop, rather than
  454. the ``hard-coded'' years 1950 and~2000, and I assume that the form will
  455. contain Field objects with these
  456. names.  Alternatively, it may provide them as global variables that are
  457. initialized somehow before [[pushButton]] is invoked, or as symbolic
  458. constants.
  459. In any event, this is the form's responsibility.
  460. \label{o-pal variables}
  461. Not surprisingly, the control flow is similar to that of the \pal/ script.
  462. <<Generate the \opaltable/ table>>=
  463. <<Create the \opaltable/ table>>
  464. FOR easter_year FROM FirstYear TO LastYear
  465.     <<\scriptsize\it Give other Windows programs a chance to run>>
  466.     <<Calculate the date of Easter>>
  467.     <<\scriptsize\it Give other Windows programs a chance to run>>
  468.     <<Add the date to \opaltable/>>
  469. ENDFOR
  470. <<\scriptsize\it Give other Windows programs a chance to run>>
  471. <<Clean up the desktop>>
  472. The only surprise here is the \LA\scriptsize\it Give other Windows programs a
  473. chance to run\RA\ chunk, which is scattered all over the
  474. place.  \windows/
  475. is a ``cooperative multitasking'' system, so each application must
  476. voluntarily give up control of the CPU from time to time, to let other
  477. applications run.  Since \objectpal/ doesn't do this
  478. automatically, I like to give other programs a chance whenever possible.
  479. I use a smaller font for this chunk name so that it's fairly
  480. unobtrusive, and doesn't interfere with the program proper.
  481. <<\scriptsize\it Give other Windows programs a chance to run>>=
  482. sleep()
  483. There's no general desktop cleanup necessary yet;  I'll add
  484. cleanup code as it becomes necessary.
  485. \subsubsection{Creating the table}
  486. It appears that the only way to create a table in \objectpal/ is to use
  487. the [[create]] pseudo-method with a [[Table]] variable.  However, only
  488. a [[TCursor]] can actually add records to a table.  There doesn't seem
  489. to be any getting around the fact that two variables are needed
  490. for what should be a one variable job.
  491. The \opaltable/ table has the same structure as
  492. \paltable/, described in Section~\ref{table structure}.
  493. <<Create the \opaltable/ table>>=
  494. dummy = create "easter2.db"
  495.             with
  496.                 "Year"  :   "S",
  497.                 "Month" :   "A5",
  498.                 "Day"   :   "S"
  499.             key "Year"
  500.         endcreate
  501. easter_table.open("easter2.db")
  502. easter_table.edit()
  503. Since the [[Table]] variable is never used for anything other than the
  504. initial creation, ``[[dummy]]'' seems an appropriate name.
  505. <<Local\/ [[pushButton]] variables>>=
  506. dummy           Table
  507. easter_table    TCursor
  508. @ %def dummy easter_table
  509. The [[easter_table]] must be closed when the method ends to make
  510. sure the last record added gets posted to the table.
  511. <<Clean up the desktop>>=
  512. easter_table.close()
  513. \subsubsection{Adding an Easter date to the table}
  514. Adding records to a table in \objectpal/ is straightforward:
  515. insert a new record, and assign the appropriate values to the appropriate
  516. fields.
  517. <<Add the date to \opaltable/>>=
  518. easter_table.insertRecord()
  519. easter_table."Year"  = easter_year
  520. easter_table."Month" = easter_month
  521. easter_table."Day"   = easter_sunday
  522. @ \nopagebreak    %    Ugh!
  523. \subsubsection{\objectpal/ wrapup}
  524. Now that the \objectpal/ method is complete, note that the only differences
  525. between it and the \pal/ script of Section~\ref{pal script} are syntactic.
  526. \subsection{Version Control Information}
  527. Since a \noweb/ program is a text file, version control
  528. information can easily be included in the woven output.  This information is updated
  529. automatically, whenever the program is ``checked in.''  The following is
  530. the relevant information for the programs in this article.
  531. \begin{list}{}{
  532.     \setlength{\labelwidth}{8em}
  533.     \setlength{\leftmargin}{9em}
  534.     \setlength{\labelsep}{0em}
  535.     \setlength{\itemsep}{0in}\setlength{\parsep}{0in}
  536.     \renewcommand{\makelabel}[1]{\bf #1:\hfil}
  537. \item[File]{\tt\RCSWorkfile}
  538. \item[Author]\RCSAuthor
  539. \item[Revision]\RCSRevision
  540. \item[Last Modified]\RCSDate
  541. \end{list}
  542. \subsection{List of Chunk Names}
  543. \noweb/ can automatically generate an index of chunk names used
  544. in the web, and the pages on which they are defined and used.  References
  545. to chunk definitions are underlined.
  546. \medskip\nowebchunks
  547. \subsection{List of Identifiers}
  548. \noweb/ can also keep track of identifier definitions and usage.
  549. \medskip\nowebindex
  550. \section{Producing Formatted Output}
  551. The \noweave/ program, discussed in Section~\ref{weaving}, does not
  552. produce its formatted output directly.
  553. It produces a file that is then processed by the \TeX
  554.     \footnote{``Insiders
  555.         pronounce the $\chi$ of \TeX\ as a Greek chi, not as an `x', so that \TeX\
  556.         rhymes with the word blecchhh.  It's the `ch' sound in Scottish words
  557.         like {\sl loch\/} or German words like {\sl ach\/}; it's a Spanish `j'
  558.         and a Russian `kh'.  When you say it correctly to your computer, the
  559.         terminal may become slightly moist.''~\cite{TeXbook}}
  560. typesetting system.  \TeX\ is the typesetting system of choice
  561. for literate programming systems for a variety of reasons:
  562. \begin{enumerate}
  563. \item
  564. \TeX\ is readily available.  Implementations exist for pretty much
  565. every computer in existence, and are usually available free of
  566. charge.  I use the excellent em\TeX\ implementation for \dos/, by
  567. Eberhard Mattes, which is freely distributable.
  568. \item
  569. \TeX\ is portable.  It is designed to be as machine-independent as
  570. possible.  Output generated by em\TeX\ on my PC and that generated
  571. by, say, a \unix/ implementation will be {\em identical}.
  572. \item
  573. \TeX\ is stable.  Before a program can be certified ``\TeX,'' it must
  574. pass a rigorous test suite called the ``trip test.''  Since \TeX\ is not
  575. a commercial product, it is not subject to the whims of a manufacturer.
  576. \item
  577. The quality of \TeX\ output is significantly better than that of any
  578. commercial word processor or desktop publisher on the market today.
  579. \end{enumerate}
  580. \noindent
  581. On the other hand, there is no reason a literate programming system {\em has\/} to
  582. use \TeX.  A number of non-\TeX\ systems exist, and many are suitable for
  583. programming in \pal/ and \objectpal/ (see Section~\ref{LP systems}).
  584. \section{Availability}
  585. \label{LP systems}
  586. Although it is not in the public domain, \noweb/ is freely
  587. distributable---this article (and the programs it generates) were created
  588. using the \dos/ implementation. Other literate programming systems suitable for \pal/
  589. and \objectpal/ are also available. \funnelweb/ and
  590. \nuweb/ are \TeX-based; \clip/ can be used with any word
  591. processor; and \wordweb/ is a collection of macros that provide a simple
  592. literate programming environment in Word for Windows.
  593. All of these systems are freely distributable.
  594. If you would like to find out more about literate programming, I
  595. recommend that you subscribe to the ``LitProg'' discussion group on the
  596. Internet.  All discussion is via electronic mail, so it should be
  597. possible to subscribe from CompuServe, or any other service that can send
  598. and receive Internet mail.  To subscribe, send a message to
  599. \verb"LitProg-Request@SHSU.edu"\footnote{CompuServe users should prepend
  600. ``\verb">INTERNET:"'' to this ad\-dress.}, and include
  601. $$\hbox{\verb'SUBSCRIBE LitProg "your name"'}$$
  602. in the body of the message.
  603. As the official welcoming notice says, ``Novices are welcome; it is
  604. intended that this group should be a place where newcomers can be
  605. welcomed into the fold as well as a place where seasoned literate
  606. programmers can discuss fine points of technique.''
  607. \section{Discussion}
  608. In the introduction, I stated that literate programming is
  609. revolutionary.  It is not ``the only game in town,'' though.
  610. The ``visual programming'' revolution is also gaining ground.
  611. Although visual programming is receiving the lion's share of
  612. publicity, I believe that literate
  613. programming is much more significant for the professional
  614. programmer.
  615. Visual programming, like \basic/ before it, is designed for the
  616. neophyte.  Writing a program is easier than ever before.  However, just as
  617. \basic/'s [[GOTO]] statement led to ``spaghetti code'' that was
  618. impossible to maintain, visual programming systems create their own
  619. maintenance problems.  In Paradox for Windows, for example, the
  620. connections between objects are invisible, creating the potential for
  621. spaghetti of another kind.  Objects can refer to other objects in many
  622. ways, and there is no way---short of
  623. examining every object---to determine whether a non-local identifier (e.g.
  624. [[FirstYear]] and [[LastYear]] in Section~\ref{o-pal variables}) is a
  625. variable, constant, or graphical object, and where in the ``container
  626. hierarchy'' it resides.  Maintaining such a system can become a nightmare.
  627. Literate programming, on the other hand, is not for the beginner.  The
  628. literate programmer must be proficient in at least two languages:  a
  629. programming language, like \pal/ or \objectpal/, and a text formatting language, like
  630. \TeX\ or a commercial word processor.  Since the bulk of a web
  631. is explanation, rather than code, the programmer has to take the
  632. time to think through the program in order to be able to explain it.  As
  633. in any programming methodology, time spent in thought ``up front''
  634. translates into reduced debugging and easier maintenance.  What literate
  635. programming adds to the mix is that the programmer's thoughts no longer
  636. disappear into thin air once the program is written; they are preserved
  637. in the web.  The programmer who maintains the web has these
  638. thoughts as a foundation for future work.
  639. For the professional programmer, {\em maintenance is everything}.  A
  640. literate program is a maintainable program.
  641. But, above all, literate programming is {\em fun}.
  642. The tedium of rearranging bits of code to cater to a compiler is
  643. gone.  In its place is a process of discovery.  As you write
  644. your explanations, the code unfolds naturally, as if it had always been
  645. there and you just now happened to find it.  The phenomenon of ``code that
  646. seems to write itself'' is common among literate programmers, as is the
  647. practice of passing programs around for comments---and actually getting
  648. them!
  649. I could go on and on.  Literate programming techniques free the
  650. programmer to focus on the uniquely human aspects of programming,
  651. leaving the computer to perform the more mundane tasks.
  652. The benefits are there for the taking.  Take them.
  653. \bibliographystyle{plain}
  654. \bibliography{litprog}
  655. \end{document}
  656. % $Log: litprog.nw%v $
  657. %Revision 2.2  1995/01/16  11:19:51  LEEW
  658. %Finally modified PVCS keywords to RCS keywords (long overdue)
  659. %Revision 2.1  1995/01/15  17:29:01  LEEW
  660. %Final cleanup; ready for submission.
  661. %Revision 2.0  1995/01/15  16:40:22  LEEW
  662. %Completed 2nd section; fixed ugly page breaks; general cleanup.
  663. %Ready for submission to the Informant?
  664. %Revision 1.6  1995/01/10  15:00:58  LEEW
  665. %Rephrasing & polishing the text.
  666. %Revision 1.5  1995/01/08  19:47:18  LEEW
  667. %Matched Informant page format as much as possible.
  668. %Revision 1.4  1995/01/08  19:25:55  LEEW
  669. %updated for new noweb (hopefully)
  670. % Revision 1.3  1995/01/08  19:06:18  LEEW
  671. % *** empty log message ***
  672. % Revision 1.1  1995/01/08  19:03:12  LEEW
  673. % Initial revision
  674. %     Rev 1.4   16 Jan 1994 15:16:24   LEEW
  675. %  Modified for new noweb.  PVCS changes made by hand(!).
  676. %     Rev 1.3   15 Jun 1993 09:57:52   LEEW
  677. %  Minor, cosmetic changes.  Article ready for submission.
  678. %     Rev 1.2   14 Jun 1993 09:51:22   LEEW
  679. %  Added Dennis' suggestions
  680. %     Rev 1.1   10 Jun 1993 10:29:14   LEEW
  681. %  Added CRG suggestions.
  682. %     Rev 1.0   09 Jun 1993 11:38:56   LEEW
  683. %  Last paragraph finished.  Minor cosmetic changes.
  684. %  First version released for comments.
  685. %     Rev 0.10   08 Jun 1993 17:34:12   LEEW
  686. %  Article complete (except for last few sentences).
  687. %     Rev 0.9   07 Jun 1993 18:11:32   LEEW
  688. %  Cosmetic work.  Added to conclusion.
  689. %     Rev 0.8   04 Jun 1993 18:08:02   LEEW
  690. %  ObjectPAL method now working, as well.
  691. %     Rev 0.7   04 Jun 1993 15:46:12   LEEW
  692. %  PAL 4.0 example works (results not yet completely checked, however).
  693. %     Rev 0.6   03 Jun 1993 17:36:56   LEEW
  694. %  General cleanup work.  Through for the day.
  695. %     Rev 0.5   03 Jun 1993 16:47:08   LEEW
  696. %  Finished section 2.
  697. %     Rev 0.4   03 Jun 1993 12:12:32   LEEW
  698. %  worked on section 2.  Started example.
  699. %     Rev 0.3   02 Jun 1993 17:29:50   LEEW
  700. %  Added Easter algorithm (and corresponding code chunks).
  701. %     Rev 0.2   02 Jun 1993 13:04:54   LEEW
  702. %  Minor changes.  Added overall structure.
  703. %     Rev 0.1   26 May 1993 16:43:48   LEEW
  704. %  Started writing.  Just a few bits and pieces so far.
  705. %     Rev 0.0   26 May 1993 15:01:14   LEEW
  706. %  Initial revision.
  707. % $Header: d:/tcc/informan/litprog.nw%v 2.2 1995/01/16 11:19:51 LEEW Exp LEEW $
  708.